package com.ojoin.ojoin.eb_spider.service.impl;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jms.Destination;

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.WebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.ojoin.ojoin.eb_spider.domain.AssistCatchData;
import com.ojoin.ojoin.eb_spider.domain.BankCardCheck;
import com.ojoin.ojoin.eb_spider.listening.CatchDateListening;
import com.ojoin.ojoin.eb_spider.service.ISLDataCatchBaseService;
import com.ojoin.ojoin.eb_spider.service.WebDriverService;
import com.ojoin.trade.common.exception.BusinessException;
import com.ojoin.trade.common.utils.CommonUtils;
import com.ojoin.trade.common.utils.Config;
import com.ojoin.trade.common.utils.LogUtils;
import com.ojoin.trade.common.utils.TimeUtils;
import com.ojoin.trade.common.utils.json.JSONUtils;
import com.ojoin.trade.common.utils.paynow.ThreeDESEncryptProvider;
import com.ojoin.trade.common_core.web.domain.TbMerchantInfo;
import com.ojoin.trade.common_core.web.domain.TbMerchantuserFinaccount;
import com.ojoin.trade.supplyloan_core.web.domain.CatchDataStartMessage;
import com.ojoin.trade.supplyloan_core.web.domain.TbSlPlatformInfo;
import com.ojoin.trade.supplyloan_core.web.domain.TbSlStattaskRunresult;

@Service
public abstract class SLDataCatchBaseServiceImpl implements
		ISLDataCatchBaseService {

	private static Logger log = LoggerFactory
			.getLogger(SLDataCatchBaseServiceImpl.class);

	ThreadLocal<AssistCatchData> assistCatchDatas = new ThreadLocal<AssistCatchData>();
	
	/**
	 * 数据抓取driver
	 */
	public final static  int verifycodeRetryCount = 5;


	/*@Autowired
	private QueueSenderServieImpl queueSenderServie;
*/
	/*@Autowired
	@Qualifier("catchDateMessage")
	private Destination destination;*/

	@Autowired
	@Qualifier("chrome")
	private WebDriverService webDriver;

	public WebDriverService getWebDriver() {
		return webDriver;
	}

	public void setWebDriver(WebDriverService webDriver) {
		this.webDriver = webDriver;
	}


	/**
	 * 对密码解密
	 * 
	 * @return
	 */
	public String getLoginPassword(String pwd) {
		String DSEKey = Config.getProperty(TbSlPlatformInfo.sl_config,
				"ipaynow.dsekey");// 3DES需要的key
		return ThreeDESEncryptProvider.decrypt(pwd, DSEKey);
	}


	@Override
	public boolean isLoginSuccess() throws Exception {
		boolean loginflag = false;
		try{

			loginflag = this.isCacheLogin();
			
			if(!loginflag){
				String username = this.getAssistCatchData().getStartMess().getPlatformUser().getUsername();
				
				String password = getLoginPassword(this.getAssistCatchData().getStartMess().getPlatformUser()
						.getPassword());

				String loginUrl = this.getAssistCatchData().getStartMess().getPlatformInfo().getLoginUrl();
				
				loginflag = LoginByUserInfo(loginUrl, username, password);
				
				if(loginflag){
					saveCookies();
				}
			}

			
		}catch (BusinessException e){
			throw e;
		}catch(Exception e){
			LogUtils.error(log, e);
			throw new BusinessException("登陆失败");
		}
		
		return loginflag;
	}

	@Override
	public boolean isSupplyInfoCorrect() throws BusinessException {
		boolean checkflag = true;

		TbMerchantInfo joinuser = this.getAssistCatchData().getStartMess().getMerchantUser();

		String catchSupplierName = catchSupplierName();

		if (!CommonUtils.isEqual(catchSupplierName, joinuser.getMchName())) {

			throw new BusinessException(catchSupplierName + "不匹配"
					+ joinuser.getMchName());
		}

		return checkflag;
	}

	@Override
	public BankCardCheck isSupplyAccountCorrect() throws BusinessException {
		boolean checkflag = true;
		
		TbMerchantuserFinaccount finaccount = this.getAssistCatchData().getStartMess()
				.getMerchantuserFinaccount();
		
		BankCardCheck bcc = catchSupplierAccount();
 
		if(CommonUtils.isEmpty(finaccount) ){
			throw new BusinessException("finaccount is null");
		}
		 
		if(CommonUtils.isEmpty(bcc) ){
			throw new BusinessException("bcc is null");
		}
		
		if (!CommonUtils.isEqual(bcc.getBankNum(),
				finaccount.getFinanceAccount())) {
			throw new BusinessException(bcc.getBankNum() + "不匹配"
					+ finaccount.getFinanceAccount());
		}

		bcc.setCorrect(checkflag);
		return bcc;
	}

	@Override
	public boolean isTaskRunSuccess() throws Exception {
		// 数据抓取

		
		 try{
			 initBusinessData();
	        }catch (BusinessException e){
				throw e;
			}catch(Exception e){
	        	LogUtils.error(log, e);
	        	throw new BusinessException("抓取结算数据出错");
	        }
		 
		 
		getBusinessData();

		return true;
	}

	/**
	 * 确保抓取数据之前账号登陆
	 * @throws Exception 
	 */
	public void initBusinessData() throws Exception{
		
	}
	
	@Override
	public void getBusinessData() throws Exception {


		 
        try{
        	getUnpayAccountData();
        }catch (BusinessException e){
			throw e;
		}catch(Exception e){
        	LogUtils.error(log, e);
        	throw new BusinessException("抓取结算数据出错");
        }
		
        try{
    		getPayAccountData();

        }catch (BusinessException e){
			throw e;
		}catch(Exception e){
        	LogUtils.error(log, e);
        	throw new BusinessException("抓取付款数据出错");
        }
        
        try{
    		getInstoreOrderData();

        }catch (BusinessException e){
			throw e;
		}catch(Exception e){
        	LogUtils.error(log, e);
        	throw new BusinessException("抓取入库数据出错");
        }
        
        try{
    		getOutstoreOrderData();
        }catch (BusinessException e){
			throw e;
		}catch(Exception e){
        	LogUtils.error(log, e);
        	throw new BusinessException("抓取出库数据出错");
        }

	}

	@Override
	public boolean init(AssistCatchData assistCatchData) {
		setAssistCatchData(assistCatchData);
		return true;
	}

	@Override
	public void catchData(AssistCatchData assistCatchData) throws Exception {
		init(assistCatchData);

		if (this.getAssistCatchData().getStartMess().getCatchType().equals(
				CatchDataStartMessage.LOCALHOST)) {
			initDownloadDir();
			initDownLoadFile();
		}

		boolean noCheck = true;
		boolean loginflag = false;

		TbSlStattaskRunresult runResult = new TbSlStattaskRunresult();

		runResult.setIdOfPlatformUser(this.getAssistCatchData().getStartMess().getPlatformUser().getId());
		runResult.setIdOfTbMerchantUser(this.getAssistCatchData().getStartMess().getPlatformUser()
				.getIdOfTbMerchantUser());
		runResult
				.setPlatformName(this.getAssistCatchData().getStartMess().getPlatformUser().getPlatformName());
		runResult.setTaskExecDate(TimeUtils.getCurDate());

		try {

			this.getAssistCatchData().getCata().setPlatformUser(this.getAssistCatchData().getStartMess().getPlatformUser());

			prepareCatchData();
			// 登陆校验
		    loginflag = isLoginSuccess();
			// 设置数据抓取服务器是否抓取成功
			if (loginflag) {
				runResult
						.setLoginSuccessFlag(ISLDataCatchBaseService.CATCHDATA__CORRECT);
			} else {
				runResult
						.setLoginSuccessFlag(ISLDataCatchBaseService.CATCHDATA__ERROR);
				return;
			}
			// 供应商名称校验
			if (noCheck || isSupplyInfoCorrect()) {
				runResult
						.setSupplyInfoCorrectFlag(ISLDataCatchBaseService.CATCHDATA__CORRECT);
			} else {
				runResult
						.setSupplyInfoCorrectFlag(ISLDataCatchBaseService.CATCHDATA__ERROR);
				return;
			}

			// 结算账户校验
			//BankCardCheck bcc = isSupplyAccountCorrect();
			
			BankCardCheck bcc = new BankCardCheck();
			bcc.setCorrect(true);
			if (!CommonUtils.isEmpty(bcc) ) {
				StringBuffer memo = new StringBuffer();
				
				memo.append(runResult.getMemo());
				
				runResult.getMemoMap().put("bank", bcc.getBankOfDeposit());
				runResult.getMemoMap().put("bankNum", bcc.getBankNum());
				
				
				if(bcc.isCorrect()){
					runResult
					.setSettleAccountCorrectFlag(ISLDataCatchBaseService.CATCHDATA__CORRECT);
				}else {
					runResult
					.setSettleAccountCorrectFlag(ISLDataCatchBaseService.CATCHDATA__ERROR);
				}
				
			} else {
				runResult
						.setSettleAccountCorrectFlag(ISLDataCatchBaseService.CATCHDATA__ERROR);
				return;
			}

			// 抓取程序运行情况
			boolean isTaskRunSuccess = isTaskRunSuccess();

			// boolean isTaskRunSuccess = true ;
			if (isTaskRunSuccess) {
				runResult
						.setGetDataSuccessFlag(ISLDataCatchBaseService.CATCHDATA__CORRECT);
			} else {
				runResult
						.setGetDataSuccessFlag(ISLDataCatchBaseService.CATCHDATA__ERROR);
				return;
			}
		} catch(BusinessException e){
			LogUtils.error(log , e);
			runResult.getMemoMap().put("exception",e.getMessage());
		}catch (Exception e) {
			LogUtils.error(log, e);
			throw e;
		} finally {

			runResult.setMemo(JSONUtils.toJSONString(runResult.getMemoMap()));
			this.getAssistCatchData().getCata().setRunResult(runResult);

			//queueSenderServie.send(destination, this.getAssistCatchData().getCata());

			LogUtils.info(log, "userid:" + this.getAssistCatchData().getStartMess().getPlatformUser().getId()
					+ "send-->");

			closeCatchData(loginflag, false);
			

		}
	}

	@Override
	public boolean isCacheLogin() throws Exception {
		boolean flag = this.getWebDriver().createByCookie(this.getAssistCatchData().getStartMess().getPlatformUser().getId()+"", this.getAssistCatchData().getStartMess().getPlatformUser().getPlatformName());
		
		// 如果cookie登陆失败，清除cookie信息
		if(!flag){
			this.getWebDriver().getDriver().manage().deleteAllCookies();
		}
		return flag ;
	}

	@Override
	public void saveCookies() throws IOException {
		this.getWebDriver().saveCookies(this.getAssistCatchData().getStartMess().getPlatformUser().getId()+"");
	}
 
	@Override
	public void closeCatchData(boolean isuser) throws BusinessException {
		// TODO
	}

	/**
	 * 获取请求的时间对参数
	 * 
	 * @param starttime
	 * @param count
	 * @return
	 * @throws Exception
	 */
	public List<Map<String, String>> getTimes(String starttime, int count)
			throws BusinessException {

		String endtime = TimeUtils.getCurDate();

		return getTimes(starttime, endtime, count);
	}

	public List<Map<String, String>> getTimes(String starttime, String endtime,
			int count) throws BusinessException {
		List<Map<String, String>> li = new ArrayList<Map<String, String>>();
		boolean flag = true;
		try {
			while (flag) {
				Map<String, String> map = new HashMap<String, String>();

				String start = TimeUtils.getDateBefore(endtime, count);
				String stime;
				String etime;
				if (TimeUtils.getDateSpaceOfDay(start, starttime) <= 0) {
					stime = start;
					etime = endtime;

					endtime = TimeUtils.getDateBefore(endtime, count + 1);
				} else {

					if (TimeUtils.getDateSpaceOfDay(starttime, endtime) <= 0) {
						stime = endtime;

					} else {
						stime = starttime;

					}
					etime = endtime;
					flag = false;
				}
				map.put("stime", stime);
				map.put("etime", etime);

				li.add(map);

			}
		} catch (Exception e) {
			throw new BusinessException("时间转化出错", e);
		}

		return li;
	}


	public void initDownloadDir() {
		String mapping_download_dir = null;

		mapping_download_dir = System.getProperties().getProperty("user.home")
				+ File.separator + "Downloads" + File.separator
				+ this.getAssistCatchData().getStartMess().getPlatformUser().getPlatformName()
				+ File.separator + this.getAssistCatchData().getStartMess().getPlatformUser().getUsername()
				+ File.separator + TimeUtils.getCurDateString();

		this.getAssistCatchData().setDownloadDir(mapping_download_dir);

		LogUtils.info(log, "下载路径download.dir 映射目录-->" + mapping_download_dir);
	}

	public boolean initDownLoadFile() throws IOException {
		File downloadFileDir = new File(this.getAssistCatchData().getDownloadDir());

		FileUtils.forceMkdir(downloadFileDir);
		File[] files = downloadFileDir.listFiles();
		if (null != files && files.length > 0) {
			for (int i = 0; i < files.length; i++) {
				File file = files[i];
				// boolean flag1 = file.renameTo(dest);
				// TODO 目前删除
				boolean flag = file.delete();
				if (!flag) {
					LogUtils.info(log, "删除文件失败");
				}
			}
		}

		return true;
	}

	@Override
	public boolean prepareCatchData() throws BusinessException, Exception {
		initDownloadDir();
		String dowmload = this.getAssistCatchData().getDownloadDir();

		if (this.getAssistCatchData().getStartMess().getCatchType().equals(
				CatchDataStartMessage.LOCALHOST)) {
			this.getWebDriver().initWebDriver(dowmload);
		} else {
			this.getWebDriver().initWebDriver(dowmload);
			//this.getWebDriver().initRemoteWebDriver(dowmload);
		}


		return true;
	}

	@Override
	public void closeCatchData(boolean islogin, boolean isuser)
			throws BusinessException {
		this.getWebDriver().close();

	}

	public AssistCatchData getAssistCatchData() {
		return assistCatchDatas.get();
	}

	public void setAssistCatchData(AssistCatchData assistCatchData) {
		assistCatchDatas.set(assistCatchData);
	}

}
